package cn.zhqr.core.service;

import cn.zhqr.command.Command;
import cn.zhqr.command.data.OrderFee;
import cn.zhqr.common.bean.ActiveMap;
import cn.zhqr.common.bean.response.ErrorCode;
import cn.zhqr.common.bean.response.OutResponse;
import cn.zhqr.common.config.GlobalConstants;
import cn.zhqr.common.external.jfinal.ModelKit;
import com.jfinal.ext.plugin.tx.DbTx;
import com.jfinal.ext.plugin.tx.Tx;
import com.jfinal.plugin.activerecord.Db;
import org.apache.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class UserOrderService {
    public static final UserOrderService instance = new UserOrderService();
    public static final Logger logger = Logger.getLogger(UserOrderService.class);

    public OutResponse<BigDecimal> updateOrderFee(UserOrder orderInput, List<OrderFee> orderFeeList){
        if(orderInput==null || orderInput.getOrderNo().compareTo(BigInteger.ZERO)<=0){
            logger.error("UserOrderService.updateOrderFee 传入的订单为空");
            return OutResponse.buildError(ErrorCode.INVALID_PARAM,"订单号为空");
        }
        OutResponse[] result = new OutResponse[1];

        DbTx.execute(new Tx() {
            @Override
            public void sql() {
                UserOrder userOrder = UserOrder.dao.findAndLockByOrderNo(orderInput.getOrderNo());

                if(userOrder.getStatus() >= UserOrder.STATUS_FINISHED){
                    logger.error("UserOrderService.updateOrderFee 传入的订单已经结算，不能再更新");
                    result[0] = OutResponse.buildError(ErrorCode.INVALID_PARAM,"订单号为空");
                }
                //计算收费明细
                List<OrderFeeDetail> orderDetailAddList = new ArrayList<>();
                List<OrderFeeDetail> orderDetailUpdateList = new ArrayList<>();
                if(orderFeeList != null){
                    BigDecimal totalAmount = BigDecimal.ZERO;
                    List<OrderFeeDetail> orderFeeDetailList = OrderFeeDetail.dao.findByOrderNo(userOrder.getOrderNo());
                    ActiveMap<Object,OrderFeeDetail> orderFeeDetailMap = (ActiveMap<Object, OrderFeeDetail>) ModelKit.toKeyModel(orderFeeDetailList,"func_no");

                    for(OrderFee orderFee : orderFeeList){
                        OrderFeeDetail orderDetail = orderFeeDetailMap.get(orderFee.getFuncNo());
                        if(orderDetail == null){
                            orderDetail = new OrderFeeDetail();
                            orderDetailAddList.add(orderDetail);
                        }else{
                            orderDetailUpdateList.add(orderDetail);
                        }
                        orderDetail.setOrderNo(userOrder.getOrderNo());
                        orderDetail.setFuncNo(orderFee.getFuncNo());
                        orderDetail.setName(Command.funcMapping.get(orderFee.getFuncNo()));
                        orderDetail.setTime(orderFee.getTime());
                        orderDetail.setAmount(orderFee.getMoney());

                        totalAmount = totalAmount.add(orderFee.getMoney());

                    }
                    if(orderDetailAddList.size()>0){
                        Db.batchSave(orderDetailAddList,10);
                    }
                    if(orderDetailUpdateList.size()>0){
                        Db.batchUpdate(orderDetailUpdateList,10);
                    }

                    if(totalAmount.compareTo(userOrder.getOrderAmount())>0){
                        userOrder.setOrderAmount(totalAmount);
                        orderInput.setOrderAmount(totalAmount);
                    }
                    userOrder.setUpdateTime(new Date());
                    userOrder.update();

                    result[0] = OutResponse.buildSuccess(totalAmount);
                }
            }

            @Override
            public void error(Exception e) {
                logger.error("UserOrderService.updateOrderFee transaction error:",e);
                result[0] = OutResponse.buildError(ErrorCode.SQL_ERROR);
            }
        });

        return result[0];
    }

    public OutResponse endOrder(BigInteger orderNo, Integer endReason){
        return endOrder(orderNo, endReason,null);
    }

    public OutResponse endOrder(BigInteger orderNo, Integer endReason,List<OrderFee> orderFeeList){
        if(orderNo == null || orderNo.compareTo(BigInteger.ZERO) <= 0){
            logger.error("订单不能为空");
            return OutResponse.buildError(ErrorCode.INVALID_PARAM,"订单号不能为空");
        }

        OutResponse[] result = new OutResponse[1];
        DbTx.execute(new Tx() {
            @Override
            public void sql() {
                UserOrder washOrder = UserOrder.dao.findAndLockByOrderNo(orderNo);

                if(washOrder.getStatus() >= UserOrder.STATUS_FINISHED){
                    result[0] = OutResponse.buildError(ErrorCode.INVALID_PARAM,"该订单已结算，请勿重复结算");
                }

                if(endReason != null){
                    washOrder.setEndReason(endReason);
                }

                Long deviceId = washOrder.getDeviceId();

                BigInteger orderNo = washOrder.getOrderNo();

                //更新订单
                updateOrderFee(washOrder,orderFeeList);

                BigDecimal orderAmount = washOrder.getOrderAmount();
                BigDecimal payAmount = orderAmount;

                long goodsId = washOrder.getGoodsId();
                UserWashCard userWashCard = UserWashCard.dao.findByIdAndUserId(goodsId,washOrder.getUserId());
                if(userWashCard == null){
                    logger.error("订单异常，强制结单: 洗车卡不存在 order_no:"+orderNo+" device_id:"+deviceId);
                    washOrder.setStatus(UserOrder.STATUS_FINISHED);
                    washOrder.setEndTime(new Date());
                    washOrder.setPayAmount(payAmount);
                    washOrder.update();
                    result[0] = OutResponse.buildError(ErrorCode.INVALID_PARAM,"洗车卡不存在");
                }

                if(userWashCard.getCardType() == WashCard.TYPE_VALUE){
                    //使用有优惠券
                    payAmount = UserCouponService.instance.useCoupon(washOrder, orderNo, orderAmount, payAmount);
                    //使用代金卡
                    payAmount = UserCardService.instance.useValueWashCard(washOrder, payAmount, userWashCard);
                }

                if(washOrder.getOrderAmount().compareTo(GlobalConstants.CARD_ONCE_MIN_AMOUNT) >= 0){
                    //消费不满1元，不计算使用次数
                    UserWashCard.dao.increaseUseTimes(userWashCard.getId());
                }


                DeviceConn deviceConn = DeviceConn.dao.findByDeviceId(deviceId);
                deviceConn.setStatus(DeviceConn.STATUS_STANDBY);
                deviceConn.setWorkFunc(0);
                deviceConn.update();


                UserCardService.instance.checkUserWashCardStatus(userWashCard);
                //结账
                washOrder.setPayAmount(payAmount);
                washOrder.setEndTime(new Date());
                washOrder.setPayTime(new Date());
                washOrder.setStatus(UserOrder.STATUS_FINISHED);
                washOrder.update();

                //添加订单分账任务，通过定时任务异步执行

                //不存在消费分账，暂时关闭消费分账。
                //OrderSplitService.instance.addOrderSplitTask(washOrder);

                result[0] = OutResponse.buildSuccess("结算完成",null);
            }

            @Override
            public void error(Exception e) {
                logger.error("UserOrderService.endOrder transaction error:",e);
            }
        });
        return result[0];
    }
}
